package com.ultrapower.util.topology;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import com.ultrapower.bean.ApplicationBean;

public class LinkDataMap {
	private final Map<LinkKey, LinkData> linkDataMap = new HashMap<>();
	private TimeWindow timeWindow;

	public LinkDataMap() {
		this(null);
	}

	public LinkDataMap(TimeWindow timeWindow) {
		this.timeWindow = timeWindow;
	}

	public Collection<LinkData> getLinkDataList() {
		return linkDataMap.values();
	}

	public void addLinkData(ApplicationBean sourceApplication, String sourceAgentId, ApplicationBean destinationApplication, 
			String destinationAgentId, long timestamp, short slotTime, long count) {
		final LinkData linkData = getLinkData(sourceApplication, destinationApplication);
		linkData.addLinkData(sourceAgentId, sourceApplication.getServiceTypeCode(), destinationAgentId,
				destinationApplication.getServiceTypeCode(), timestamp, slotTime, count);
	}

	@Override
	public String toString() {
		return "LinkDataMap [" + linkDataMap + "]";
	}

	public void addLinkDataMap(LinkDataMap linkDataMap) {
		if (linkDataMap == null) {
			throw new NullPointerException("linkDataMap must not be null");
		}
		for (LinkData copyLinkData : linkDataMap.linkDataMap.values()) {
			addLinkData(copyLinkData);
		}
	}

	public void addLinkData(LinkData copyLinkData) {
		if (copyLinkData == null) {
			throw new NullPointerException("copyLinkData must not be null");
		}
		ApplicationBean fromApplication = copyLinkData.getFromApplication();
		ApplicationBean toApplication = copyLinkData.getToApplication();
		LinkData linkData = getLinkData(fromApplication, toApplication);
		linkData.add(copyLinkData);
	}

	private LinkData getLinkData(ApplicationBean fromApplication, ApplicationBean toApplication) {
		final LinkKey key = new LinkKey(fromApplication, toApplication);
		LinkData findLink = linkDataMap.computeIfAbsent(key, k -> new LinkData(fromApplication, toApplication, timeWindow));
		return findLink;
	}

	// test api
	public long getTotalCount() {
		long totalCount = 0;
		for (LinkData linkData : linkDataMap.values()) {
			totalCount += linkData.getTotalCount();
		}
		return totalCount;
	}

	public int size() {
		return linkDataMap.size();
	}

	public LinkData getLinkData(LinkKey findLinkKey) {
		if (findLinkKey == null) {
			throw new NullPointerException("findLinkKey must not be null");
		}
		return this.linkDataMap.get(findLinkKey);
	}

	public TimeWindow getTimeWindow() {
		return timeWindow;
	}

	public void setTimeWindow(TimeWindow timeWindow) {
		this.timeWindow = timeWindow;
	}
}
